package br.com.wssa.email.ejb.service.impl;

import java.util.logging.Logger;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;

import br.com.wssa.email.constants.ExceptionConstants;
import br.com.wssa.email.dto.EmailDTO;
import br.com.wssa.email.ejb.service.EmailProducerService;
import br.com.wssa.email.exception.EmailException;


/**
 * EmailProducerService
 */
@Stateless(name = EmailProducerService.JNDI_NAME, mappedName = EmailProducerService.JNDI_NAME)
public class EmailProducerServiceImpl implements EmailProducerService {

	public static final Logger LOGGER = Logger.getLogger(EmailProducerServiceImpl.class.getName());
	
	private static final long serialVersionUID = -1L;
	private static final String NAME_CONNECTION_FACTORY = "java:/ConnectionFactory";
	private static final String NAME_QUEUE_EMAIL = "java:jboss/jms/queue/EmailQueue";

	@Resource(mappedName = NAME_CONNECTION_FACTORY)
	private QueueConnectionFactory fabrica;

	@Resource(mappedName = NAME_QUEUE_EMAIL)
	private Queue fila;

	/**
	 * enviarEmail.
	 */
	public void enviarEmail(EmailDTO EmailDTO) throws EmailException {
		executaEnvioEmail(EmailDTO);
	}

	/**
	 * executaEnvioEmail.
	 */
	private void executaEnvioEmail(EmailDTO EmailDTO) throws EmailException {
		LOGGER.info("executaEnvioEmail inicio");
		Session sessao = null;
		QueueConnection conexao = null;
		ObjectMessage mensagem = null;
		MessageProducer produtor = null;

		try {
			if (this.fabrica == null) {
				throw new EmailException(ExceptionConstants.NAO_ENCONTRADA_MESSAGE_QUEUE_CONNECTION_FACTORY, null);
			}

			try {
				conexao = this.fabrica.createQueueConnection();
			} catch (JMSException e) {
				throw new EmailException(ExceptionConstants.ERRO_AO_CRIAR_CONEXAO_MESSAGE_QUEUE, e);
			}
			try {
				sessao = conexao.createSession(false, Session.CLIENT_ACKNOWLEDGE);
			} catch (JMSException e) {
				throw new EmailException(ExceptionConstants.ERRO_AO_CRIAR_SESSION_MESSAGE_QUEUE, e);
			}

			try {
				if (this.fila == null) {
					this.fila = sessao.createQueue(NAME_QUEUE_EMAIL);
				}
			} catch (JMSException e) {
				throw new EmailException(ExceptionConstants.NAO_ENCONTRADA_MESSAGE_QUEUE, null);
			}

			try {
				mensagem = sessao.createObjectMessage();
				mensagem.setObject(EmailDTO);
			} catch (JMSException e) {
				throw new EmailException(ExceptionConstants.ERRO_AO_CRIAR_OBJECT_MESSAGE, null);
			}

			try {
				produtor = sessao.createProducer(this.fila);
				produtor.send(mensagem);
			} catch (JMSException e) {
				throw new EmailException(ExceptionConstants.ERRO_AO_CRIAR_MESSAGE_PRODUCER, e);
			}

		} catch (EmailException jmsEx) {
			throw new EmailException(ExceptionConstants.ERRO_AO_ENVIAR_JMS, jmsEx);
		} finally {
			this.finalizaConexao(sessao, conexao, produtor);
		}
		LOGGER.info("executaEnvioEmail fim");
	}

	/**
	 * Finaliza conexao.
	 */
	private void finalizaConexao(final Session sessao, final QueueConnection conexao, final MessageProducer produtor) throws EmailException {
		try {
			if (sessao != null) {
				sessao.close();
			}
		} catch (JMSException jmsEx) {
			throw new EmailException(ExceptionConstants.ERRO_CLOSE_SESSION_MESSAGE_QUEUE, jmsEx);
		}

		try {
			if (conexao != null) {
				conexao.close();
			}
		} catch (JMSException jmsEx) {
			throw new EmailException(ExceptionConstants.ERRO_CLOSE_SESSION_MESSAGE_QUEUE, jmsEx);
		}

		try {
			if (produtor != null) {
				produtor.close();
			}
		} catch (JMSException jmsEx) {
			throw new EmailException(ExceptionConstants.ERRO_CLOSE_SESSION_MESSAGE_QUEUE, jmsEx);
		}
	}
}